home *** CD-ROM | disk | FTP | other *** search
/ Mac Power 1997 December / MACPOWER-1997-12.ISO.7z / MACPOWER-1997-12.ISO / AMUG / PROGRAMMING / Raven 1.2 Examples.sit / Raven 1.2 Examples / Quill / Source / RsrcPopupMenu.cpp < prev    next >
C/C++ Source or Header  |  1997-08-26  |  6KB  |  229 lines

  1. /*
  2.  *    File:        RsrcPopupMenu.cpp
  3.  *    Function:    A popup menu used for picking things like SPen and STextTrait resource.
  4.  *    Written by:    Jesse Jones
  5.  *
  6.  *  Copyright ゥ 1997 Jesse Jones. 
  7.  *    For conditions of distribution and use, see copyright notice in ZTypes.h  
  8.  *
  9.  *    Change History (most recent first):
  10.  *
  11.  *         <1>     5/11/97    JDJ        Created
  12.  */
  13.  
  14. #include "RsrcPopupMenu.h"
  15.  
  16. #include <Vector.h>
  17.  
  18. #include <ZDialogBoxes.h>
  19. #include <ZIntConversions.h>
  20. #include <ZResUtils.h>
  21. #include <ZStringUtils.h>
  22. #include <ZView.h>
  23.  
  24.  
  25. __MSL_FIX_ITERATORS__(SResourceInfo);
  26. __MSL_FIX_ITERATORS__(const SResourceInfo);
  27.  
  28. // ===================================================================================
  29. //    Internal Functions
  30. // ===================================================================================
  31.  
  32. //---------------------------------------------------------------
  33. //
  34. // GetIndInfo
  35. //
  36. // This menu is non-essential so we'll eat any errors.
  37. //
  38. //---------------------------------------------------------------
  39. static SResourceInfo GetIndInfo(ResType type, short index)
  40. {
  41.     SResourceInfo info;
  42.     info.id = 0;
  43.     
  44.     Handle hand = nil;
  45.  
  46.     {
  47.     TNoResLoad noLoad;
  48.         hand = GetIndResource(type, index);
  49.     }
  50.         
  51.     if (hand != nil) {
  52.         Str255    name;
  53.  
  54.         GetResInfo(hand, &info.id, &info.type, name);
  55.         if (ResError() == noErr)
  56.             info.name = PStrToStr(name);
  57.         
  58.         ReleaseResource(hand);
  59.     }
  60.     
  61.     return info;
  62. }
  63.  
  64. inline bool operator==(const SResourceInfo& lhs, const SResourceInfo& rhs)    {return lhs.id == rhs.id;}
  65. inline bool operator<(const SResourceInfo& lhs, const SResourceInfo& rhs)    {return lhs.id < rhs.id;}
  66.  
  67. #pragma mark -
  68.  
  69. // ===================================================================================
  70. //    class CRsrcPopupMenu
  71. // ===================================================================================
  72.  
  73. static TReanimatorRegister<CRsrcPopupMenu> sRsrcPopupRegistrar;
  74.  
  75. //---------------------------------------------------------------
  76. //
  77. // CRsrcPopupMenu::~CRsrcPopupMenu
  78. //
  79. //---------------------------------------------------------------
  80. CRsrcPopupMenu::~CRsrcPopupMenu()
  81. {
  82. }
  83.  
  84.  
  85. //---------------------------------------------------------------
  86. //
  87. // CRsrcPopupMenu::CRsrcPopupMenu
  88. //
  89. //---------------------------------------------------------------
  90. CRsrcPopupMenu::CRsrcPopupMenu(const string& name, TView* superView, const TRect& frame, const string& title, short titleWidth, const string& mesg, ResID menuID) : TPopupMenu(name, superView, frame, title, titleWidth, mesg, menuID)
  91. {
  92.     mRsrcType = '????';
  93.     mRsrcID   = 0;
  94. }
  95.  
  96.  
  97. //---------------------------------------------------------------
  98. //
  99. // CRsrcPopupMenu::Create                                [static]
  100. //
  101. //---------------------------------------------------------------
  102. MReanimatable* CRsrcPopupMenu::Create(MReanimatable* parent)
  103. {
  104.     return new CRsrcPopupMenu("????", dynamic_cast<TView*>(parent), TRect(0, 0, 144, 20), "Menu", 60, kNothingCmd, 249);
  105. }
  106.  
  107.  
  108. //---------------------------------------------------------------
  109. //
  110. // CRsrcPopupMenu::SetID
  111. //
  112. //---------------------------------------------------------------
  113. void CRsrcPopupMenu::SetID(ResID id)
  114. {
  115.     if (id != mRsrcID) {    
  116.         mRsrcID = id;
  117.         
  118.         string text = LongToStr(mRsrcID);
  119.         
  120.         bool found = false;
  121.         short count = this->GetCount();
  122.         for (short index = 0; index < count - 3 && !found; index++) {
  123.             string item = this->GetItem(index);
  124.             if (item.find(text) == 0) {
  125.                 this->SetValue(index + 1);
  126.                 found = true;
  127.             }
  128.         }
  129.         
  130.         if (!found)
  131.             this->SetValue(count);
  132.     }
  133. }
  134.  
  135. #pragma mark ハ
  136.  
  137. //---------------------------------------------------------------
  138. //
  139. // CRsrcPopupMenu::OnReanimated    SPen
  140. //
  141. //---------------------------------------------------------------
  142. void CRsrcPopupMenu::OnReanimated()
  143. {
  144.     Inherited::OnReanimated();
  145.         
  146.     // Find out which resource type we're dealing with.
  147.     MenuHandle menuH = this->GetMenuHandle();
  148.     if ((**menuH).menuID == 312)                        // ・・・ハwould be much nicer to stream this in
  149.         mRsrcType = 'Txtr';
  150.     else if ((**menuH).menuID >= 313 && (**menuH).menuID <= 318)
  151.         mRsrcType = 'Pen ';
  152.     else
  153.         DEBUGSTR("CRsrcPopupMenu::OnReanimated can't handle this id!");
  154.         
  155.     vector<SResourceInfo, allocator<SResourceInfo> > infos;
  156.     
  157.     // Get a list of all the resources.
  158.     short count = CountResources(mRsrcType);
  159.     for (short index = 1; index <= count; index++) {
  160.         SResourceInfo info = GetIndInfo(mRsrcType, index);
  161.         if (info.id != 0)
  162.             infos.push_back(info);
  163.     }
  164.     
  165.     // Sort the list by id (GetIndResource returns resources in
  166.     // the order they were added to the resource fork).
  167.     sort(infos.begin(), infos.end()); 
  168.     
  169.     // Add the infos to the menu.
  170.     if (infos.size() > 0) {
  171.         short count = this->GetCount();
  172.         short index = count - 2;
  173.         
  174.         vector<SResourceInfo, allocator<SResourceInfo> >::iterator iter = infos.begin();
  175.         while (iter != infos.end()) {
  176.             SResourceInfo info = *iter++;
  177.             
  178.             if (iter == infos.end() || info != *iter) {        // Don't add the same id more than once
  179.                 if (info.id >= 256) {                        // Don't add Raven or Quill traits.
  180.                     string text = LongToStr(info.id) + " (" + info.name + ")";                
  181.                     this->InsertItem(text, index++);
  182.                 }
  183.             }
  184.         }
  185.         
  186.         if (this->GetCount() != count)
  187.             this->InsertItem("(-", count - 2);
  188.     }
  189.                         
  190.     // Update mRsrcID (based on the initial item).
  191.     this->DoUpdateID();
  192. }
  193.  
  194.  
  195. //---------------------------------------------------------------
  196. //
  197. // CRsrcPopupMenu::OnClickedControl
  198. //
  199. //---------------------------------------------------------------
  200. void CRsrcPopupMenu::OnClickedControl()
  201. {
  202.     Inherited::OnClickedControl();
  203.     
  204.     if (this->GetValue() == this->GetCount())
  205.         (void) GetShort(208, &mRsrcID);
  206.     else
  207.         this->DoUpdateID();
  208. }
  209.  
  210. #pragma mark ハ
  211.  
  212. //---------------------------------------------------------------
  213. //
  214. // CRsrcPopupMenu::DoUpdateID
  215. //
  216. //---------------------------------------------------------------
  217. void CRsrcPopupMenu::DoUpdateID()
  218. {
  219.     short value = this->GetValue();
  220.     
  221.     string item = this->GetItem(value - 1);
  222.     string text = Before(item, "(");
  223.         
  224.     if (text != "")
  225.         mRsrcID = StrToLong(text);
  226. }
  227.  
  228.  
  229.